package com.ls.fw.data.bean;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import com.ls.fw.data.enums.FieldType;
import com.ls.fw.data.visitor.FieldVisitor;

public class Table implements Serializable,Cloneable {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	private String schemaName = "";
	private String name = "";
	// 别名
	private String alias = "";

	// 建立时间
	private Date Date;

	// 备注
	private String remark = "";

	// 主键是否自动生成
	private boolean autoGenerateKey = true;

	// 列簇
	private List<Column> columns = new ArrayList<Column>();

	public Table(String schemaName, String name) {
		this(schemaName, name, null);
	}
	

	public Table(String schemaName, String name, String alias ) {
		super();
		this.schemaName = schemaName;
		this.name = name;
		this.alias = alias;
	}


	public Column addField(String name, Object value) {
		Column f = new Column(name, value);
		this.columns.add(f);
		return f;
	}

	public Column addField(String name) {
		Column f = new Column(name);
		this.columns.add(f);
		return f;
	}

	public Column addField(String name, FieldType type) {
		Column f = new Column(name).setFieldType(type);
		this.columns.add(f);
		return f;
	}
	
	
	public Column addField(Column f) {
		this.columns.add(f);
		return f;
	}

	public String getAlias() {
		return alias;
	}

	public Table setAlias(String alias) {
		this.alias = alias;
		return this;
	}

	public Date getDate() {
		return Date;
	}

	public Table setDate(Date Date) {
		this.Date = Date;
		return this;
	}

	public String getRemark() {
		return remark;
	}

	public Table setRemark(String remark) {
		this.remark = remark;
		return this;
	}

	public boolean isAutoGenerateKey() {
		return autoGenerateKey;
	}

	public Table setAutoGenerateKey(boolean autoGenerateKey) {
		this.autoGenerateKey = autoGenerateKey;
		return this;
	}

	public List<Column> getFields() {
		return columns;
	}

	public Table setFields(List<Column> columns) {
		this.columns = columns;
		return this;
	}

	public int getVersion() {
		return version;
	}

	public Table setVersion(int version) {
		this.version = version;
		return this;
	}

	private int version = 0;

	public String getSchemaName() {
		return schemaName;
	}

	public Table setSchemaName(String schemaName) {
		this.schemaName = schemaName;
		return this;
	}


	public String getFullName() {
		return (schemaName != null && !"".equals(schemaName))?(schemaName+"_"+name):name;
	}
	
	
	public String getName() {
		return name;
	}

	public Table setName(String name) {
		this.name = name;
		return this;
	}

	@Override
	public String toString() {
		return "Table [schemaName=" + schemaName + ", name=" + name
				+ ", alias=" + alias + ", Date=" + Date
				+ ", remark=" + remark + ", autoGenerateKey=" + autoGenerateKey
				+ ", fields=" + columns.size() + ", version=" + version + "]";
	}

	public String string() {
		return "schemaName=" + schemaName + ", name=" + name + ", alias="
				+ alias + ", Date=" + Date + ", remark=" + remark
				+ ", autoGenerateKey=" + autoGenerateKey + ", version="
				+ version + "]";
	}

	/**
	 * 获取列集合的map对象<列名，列实体>
	 * 
	 * @author ls 2014年11月25日上午10:19:06
	 * @return
	 */
	public Map<String, Column> getFieldMap() {
		Map<String, Column> fieldMap = new LinkedHashMap<String, Column>();
		for (Column column : this.getFields()) {
			fieldMap.put(column.getName(), column);
		}
		return fieldMap;
	}

	/**
	 * 获取需要建立索引列集合的map对象<索引名，列实体>,键值为索引列名
	 * 
	 * @author ls 2014年11月25日上午10:18:59
	 * @return
	 */
	public Map<String, Column> getIndexMap() {
		Map<String, Column> indexMap = new LinkedHashMap<String, Column>();
		for (Column column : this.getFields()) {
			if (column.isIndex() || column.isForeignkey()
					|| column.isPrimaryKey()) {
				indexMap.put(column.getIndexName(), column);
			}
		}
		return indexMap;
	}

	/**
	 * 获取需要建立索引列集合的map对象<列名，列实体>，键值为列名
	 * 
	 * @author ls 2014年11月25日上午10:18:51
	 * @return
	 */
	public Map<String, Column> getNameIndexMap() {
		Map<String, Column> indexMap = new LinkedHashMap<String, Column>();
		for (Column column : this.getFields()) {
			if (column.isIndex() || column.isForeignkey()
					|| column.isPrimaryKey()) {
				indexMap.put(column.getName(), column);
			}
		}
		return indexMap;
	}

	/**
	 * 获取需要建立索引的列
	 * 
	 * @author ls 2014年11月25日上午10:19:51
	 * @return
	 */
	public List<Column> getIndexFields() {
		List<Column> indexList = new ArrayList<Column>();
		for (Column column : this.getFields()) {
			if (column.isIndex() || column.isForeignkey()
					|| column.isPrimaryKey()) {
				// 主键列和搜索列都需要建立索引
				indexList.add(column);
			}
		}
		return indexList;
	}

	/**
	 * 获取列名列表
	 * 
	 * @author ls 2014年11月25日上午10:21:27
	 * @return
	 */
	public List<String> getFieldsStr() {
		List<String> columnsStr = new ArrayList<String>();
		for (Column column : this.getFields()) {
			columnsStr.add(column.getName());
		}
		return columnsStr;
	}

	/**
	 * 获取主键列
	 * 
	 * @author ls 2014年11月25日上午10:22:18
	 * @return
	 */
	public Column getPriKey() {
		Column priKey = null;
		for (Column column : this.getFields()) {
			if (column.isPrimaryKey()) {
				priKey = column;
				break;
			}
		}
		return priKey;
	}

	/**
	 * 获取外键列
	 * 
	 * @author ls 2014年11月25日上午10:22:22
	 * @return
	 */
	public Column getForKey() {
		Column priKey = null;
		for (Column column : this.getFields()) {
			if (column.isForeignkey()) {
				priKey = column;
				break;
			}
		}
		return priKey;
	}

	/**
	 * 根据名称获取列对象
	 * 
	 * @author ls 2014年11月25日上午10:23:58
	 * @param name
	 * @return
	 */
	public Column getField(String name) {
		Column column = null;
		for (Column col : this.getFields()) {
			if (col.getShowName().equals(name) || col.getName().equals(name)) {
				column = col;
				break;
			}
		}
		return column;
	}

	/**
	 * 获取索引列
	 * 
	 * @author ls 2014年11月25日上午10:23:42
	 * @param name
	 * @return
	 */
	public Column getIndexField(String name) {
		Column Column = null;
		for (Column col : this.getFields()) {
			if ((col.isPrimaryKey() || col.isForeignkey() || col
					.isIndex()) 
					&& (col.getShowName().equals(name) || col.getName().equals(name))) {
				Column = col;
				break;
			}
		}
		return Column;
	}

	/**
	 * 获取索引名称
	 * 
	 * @author ls 2014年11月25日上午10:23:47
	 * @param name
	 * @return
	 */
	public String getIndexName(String name) {
		Column column = this.getIndexField(name);
		return column != null ? column.getIndexName() : "";
	}
	
	
	public void accept(FieldVisitor fieldVisitor) {
		for (Column column : columns) {
			fieldVisitor.visit(column);
		}
	}


	/* (non-Javadoc)
	 * @see java.lang.Object#hashCode()
	 */
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((name == null) ? 0 : name.hashCode());
		result = prime * result
				+ ((schemaName == null) ? 0 : schemaName.hashCode());
		return result;
	}


	/* (non-Javadoc)
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Table other = (Table) obj;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		if (schemaName == null) {
			if (other.schemaName != null)
				return false;
		} else if (!schemaName.equals(other.schemaName))
			return false;
		return true;
	}
}
